package com.oauth.inner.service;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.config.annotation.Service;
import com.oauth.inner.rpc.IRAccountService;
import com.oauth.resp.BaseDto;
import com.oauth.resp.ResultCode;
import com.oauth.resp.ResultUtil;
import com.oauth.user.dto.AccountDto;
import com.oauth.user.enums.CommonStatusEnum;
import com.oauth.user.pojo.Account;
import com.oauth.user.pojo.AccountBind;
import com.oauth.user.pojo.Client;
import com.oauth.user.redis.AccountRedisService;
import com.oauth.user.service.AccountService;
import com.oauth.user.service.ClientService;
import com.oauth.util.AESUtil;
import com.oauth.util.MD5Util;
import com.oauth.util.SHAUtil;
import com.oauth.util.StringFormatUtil;

@Service(interfaceClass = IRAccountService.class, version = "v1.0")
@Component
public class RAccountService implements IRAccountService {

    @Autowired
    private AccountService accountService;
    @Autowired
    private ClientService clientService;
    @Autowired
    private AccountRedisService accountRedisService;
    
    @Override
    public BaseDto<Serializable> login(String account, String clientId, String sign) {
        Client client = clientService.selectClientByClientId(clientId);
        
        //客户端是否可用
        if(Objects.isNull(client) || client.getStatus() == CommonStatusEnum.DISABLED.getStatus()) {
            return ResultUtil.result(ResultCode.UNABLE_CLIENT);
        }
        
        //解密
        String decrypt = AESUtil.decrypt(sign, client.getClientSecret());
        if(Objects.isNull(decrypt)) {
            return ResultUtil.result(ResultCode.UNABLE_SECRET);
        }
        
        Map<String, String> decryptMap = StringFormatUtil.mediaFormToMap(decrypt);
        
        String password = decryptMap.get("password");
        String time = decryptMap.get("timestamp");
        if(Objects.isNull(password) || Objects.isNull(time)) {
            return ResultUtil.result(ResultCode.UNABLE_SECRET);
        }

        AccountBind bind = accountService.selectAccountBindByClientIdAndAccount(clientId, account);
        
        //账户信息判断
        if(Objects.isNull(bind)) {
            return ResultUtil.result(ResultCode.UNABLE_LOGIN);
        }
        
        Account data = accountService.selectAccountByAccount(account);
        
        if(data.getStatus() == CommonStatusEnum.DISABLED.getStatus()) {
            return ResultUtil.result(ResultCode.UNABLE_ACOUNT);
        }
        
        //密码验证
        String sha256 = SHAUtil.SHA256(password + data.getSalt());
        if(!data.getPassword().equals(sha256)) {
            return ResultUtil.result(ResultCode.CHECK_FAILED);
        }
        
        //获取token
        String token = MD5Util.md5(clientId + account + time);
        accountRedisService.put(clientId, account, token);
        
        AccountDto dto = new AccountDto();
        dto.setAccount(account);
        dto.setImg(data.getImg());
        dto.setNickname(data.getNickname());
        
        HashMap<String, Object> dtoMap = new HashMap<>();
        dtoMap.put("account", dto);
        dtoMap.put("token", token);
        
        return ResultUtil.success(dtoMap);
    }

    @Override
    public BaseDto<Serializable> logout(String account, String clientId, String sign) {
        accountRedisService.del(clientId, account);
        return ResultUtil.success();
    }
    
    @Override
    public boolean checkToken(String account, String clientId, String token, String sign) {
        String tokenCache = accountRedisService.get(clientId, account);
        if(Objects.nonNull(tokenCache) && tokenCache.equals(token)) {
            return true;
        }
        
        return false;
    }
}
